package com.iot08.api.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iot08.common.constant.Const;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.HttpReq;
import com.iot08.common.utils.RandomUtil;
import com.iot08.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.*;

/**
 * @version 1.0
 * @Description:
 * @time: 2021/1/18 17:41
 * @author: Rock
 */
@Slf4j
public class CXUtil {


    /**
     * 查询物联卡白名单
     *
     * @param iccid
     * @time: 2021/1/19 10:09
     * @author: Rock
     * @version 1.0
     */
    public static JSONObject queryCXCardWhiteList(String iccid) {
        Map<String, Object> params = new HashMap<>();
        params.put("msisdn", iccid);
        params.put("type", 4);
        params.put("appId", Const.CX_APP_ID);
        params.put("nonceStr", RandomUtil.getRandomStr(32));
        params.put("timestamp", DateUtil.dateToStr(new Date(), DateUtil.FORMAT_1));
        params.put("signature", sign(params));
        String result = HttpReq.sendPostJson(Const.CX_VOICE_WHITE_URL, JSON.toJSONString(params));
        if (StringUtil.isNotBlank(result)) {
            JSONObject resultJson = JSON.parseObject(result);
            if (Const.INT_1.equals(resultJson.getInteger("code"))) {
                return resultJson.getJSONObject("body");
            }
        }
        log.info("queryCXCardWhiteList is fail. iccid = {}", iccid);
        return null;
    }

    /**
     * @param iccid
     * @param nick
     * @param phone
     * @time: 2021/1/19 10:14
     * @author: Rock
     * @version 1.0
     */
    public static boolean addCXCardWhiteList(String iccid, String nick, String phone) {
        Map<String, Object> params = new HashMap<>();
        params.put("msisdn", iccid);
        params.put("type", 4);
        params.put("operType", "add");
        params.put("nick", nick);
        params.put("phone", phone);
        params.put("appId", Const.CX_APP_ID);
        params.put("nonceStr", RandomUtil.getRandomStr(32));
        params.put("timestamp", DateUtil.dateToStr(new Date(), DateUtil.FORMAT_1));
        params.put("signature", sign(params));
        String result = HttpReq.sendPostJson(Const.CX_VOICE_WHITE_MANAGER_URL, JSON.toJSONString(params));
        if (StringUtil.isNotBlank(result)) {
            JSONObject resultJson = JSON.parseObject(result);
            if (Const.INT_1.equals(resultJson.getInteger("code"))) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param iccid
     * @param nick
     * @param phone
     * @time: 2021/1/19 11:07
     * @author: Rock
     * @version 1.0
     */
    public static boolean updateCXCardWhiteListNickName(String iccid, String nick, String phone) {
        Map<String, Object> params = new HashMap<>();
        params.put("msisdn", iccid);
        params.put("type", 4);
        params.put("nick", nick);
        params.put("phone", phone);
        params.put("appId", Const.CX_APP_ID);
        params.put("nonceStr", RandomUtil.getRandomStr(32));
        params.put("timestamp", DateUtil.dateToStr(new Date(), DateUtil.FORMAT_1));
        params.put("signature", sign(params));
        String result = HttpReq.sendPostJson(Const.CX_UPDATE_WHITE_URL, JSON.toJSONString(params));
        if (StringUtil.isNotBlank(result)) {
            JSONObject resultJson = JSON.parseObject(result);
            if (Const.INT_1.equals(resultJson.getInteger("code"))) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param iccid
     * @time: 2021/1/23 18:20
     * @author: Rock
     * @version 1.0
     */
    public static JSONObject getCXCardInfo(String iccid) {
        Map<String, Object> params = new HashMap<>();
        params.put("cardNumber", iccid);
        params.put("appId", Const.CX_APP_ID);
        params.put("nonceStr", RandomUtil.getRandomStr(32));
        params.put("timestamp", DateUtil.dateToStr(new Date(), DateUtil.FORMAT_1));
        params.put("signature", sign(params));
        String result = HttpReq.sendPostJson(Const.CX_GET_SIM_URL, JSON.toJSONString(params));
        if (StringUtil.isNotBlank(result)) {
            return JSON.parseObject(result);
        }
        return null;
    }

    /**
     * 签名加密
     *
     * @param paramValues
     * @time: 2021/1/18 17:43
     * @author: Rock
     * @version 1.0
     */
    public static String sign(Map<String, Object> paramValues) {
        try {
            StringBuilder sb = new StringBuilder();
            List<String> paramNames = new ArrayList<String>(paramValues.size());
            paramNames.addAll(paramValues.keySet());
            Collections.sort(paramNames);
            sb.append(Const.CX_APP_SECRET);
            for (String paramName : paramNames) {
                sb.append(paramName).append(paramValues.get(paramName).toString());
            }
            sb.append(Const.CX_APP_SECRET);
            byte[] sha1Digest = getSHA1Digest(sb.toString());
            String rst = byte2hex(sha1Digest);
            log.info("calc sign, param: {}, sign: {}", sb.toString(), rst);
            return rst;
        } catch (IOException e) {
            log.error("sign error", e);
            return null;
        }
    }

    public static byte[] getSHA1Digest(String data) throws IOException {
        byte[] bytes = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            bytes = md.digest(data.getBytes("UTF-8"));
        } catch (GeneralSecurityException gse) {
            throw new IOException(gse);
        }
        return bytes;
    }

    /**
     * 二进制转十六进制字符串
     *
     * @param bytes
     * @return
     */
    public static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }


}
